package com.heima.article.service.Impl;

import com.alibaba.fastjson.JSON;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.HotArticle;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.zxc.apis.wemedia.IWemediaClient;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.heima.common.constants.ArticleConstants.*;

@Service
@Transactional
@Slf4j
public class HotArticleServiceImpl implements HotArticleService {

    @Resource
    private ApArticleMapper apArticleMapper;

    @Resource
    private IWemediaClient iWemediaClient;
    @Resource
    private CacheService cacheService;

    @Override
    public void ComputeHotArticle() {
        Date date = new DateTime().minusDays(5).toDate();
        List<ApArticle> apArticles = apArticleMapper.findArticleListBy5Days(date);
        if (apArticles == null || apArticles.size() == 0) {
            return;
        }
        List<HotArticle> hotArticles = ComputeHotArticleScore(apArticles);
        //缓存各个频道的前30条文章
        cacheChannelToRedis(hotArticles);
        //推荐前30条文章
        sortAndCache(DEFAULT_TAG, hotArticles);
    }

    private void cacheChannelToRedis(List<HotArticle> hotArticles) {
        ResponseResult result = iWemediaClient.findChannels();
        if (result.getCode() != 200) {
            System.out.println(result.getCode());
            throw new RuntimeException("获取频道列表时异常");
        }
        String jsonString = JSON.toJSONString(result.getData());
        List<WmChannel> WmChannels = JSON.parseArray(jsonString, WmChannel.class);
        if (CollectionUtils.isEmpty(WmChannels)) {
            throw new RuntimeException("获取频道列表时异常");
        }
        for (WmChannel wmChannel : WmChannels) {

            List<HotArticle> hotArticleList = hotArticles.stream().filter(hotArticle -> Objects.equals(hotArticle.getChannelId(), wmChannel.getId())).collect(Collectors.toList());
            sortAndCache(wmChannel.getId().toString(), hotArticleList);
        }


    }

    private void sortAndCache(String key, List<HotArticle> hotArticleList) {
        hotArticleList = hotArticleList.stream().sorted(Comparator.comparing(HotArticle::getScore).reversed()).collect(Collectors.toList());
        if (hotArticleList.size() > 30) {
            hotArticleList = hotArticleList.subList(0, 30);
        }

        cacheService.set(HOT_ARTICLE_FIRST_PAGE + key, JSON.toJSONString(hotArticleList));
    }

    private List<HotArticle> ComputeHotArticleScore(List<ApArticle> apArticles) {
        if (apArticles == null || apArticles.size() == 0) {
            return null;
        }
        return apArticles.stream()
                .map(apArticle -> {
                    HotArticle hotArticle = new HotArticle();
                    BeanUtils.copyProperties(apArticle, hotArticle);
                    int score = 0;
                    if (apArticle.getLikes() != null) {
                        score += apArticle.getLikes() * HOT_ARTICLE_LIKE_WEIGHT;
                    }
                    if (apArticle.getViews() != null) {
                        score += apArticle.getViews() * HOT_ARTICLE_VIEWS_WEIGHT;
                    }
                    if (apArticle.getCollection() != null) {
                        score += apArticle.getCollection() * HOT_ARTICLE_COLLECTION_WEIGHT;
                    }
                    if (apArticle.getComment() != null) {
                        score += apArticle.getComment() * HOT_ARTICLE_COMMENT_WEIGHT;
                    }
                    hotArticle.setScore(score);
                    return hotArticle;
                }).collect(Collectors.toList());
    }
}
